package ynu.edu.controller;

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 容错机制监控控制器
 * 提供熔断器、限流等状态监控
 */
@RestController
@RequestMapping("/resilience")
public class ResilienceMonitorController {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Autowired(required = false)
    private CircuitBreakerRegistry circuitBreakerRegistry;

    /**
     * 获取所有熔断器状态
     */
    @GetMapping("/circuit-breakers")
    public ResponseEntity<Map<String, Object>> getAllCircuitBreakers() {
        Map<String, Object> response = new HashMap<>();
        
        if (circuitBreakerRegistry != null) {
            Map<String, Object> circuitBreakers = circuitBreakerRegistry.getAllCircuitBreakers()
                    .asJava()
                    .stream()
                    .collect(Collectors.toMap(
                            CircuitBreaker::getName,
                            this::getCircuitBreakerInfo
                    ));
            
            response.put("circuitBreakers", circuitBreakers);
            response.put("totalCount", circuitBreakers.size());
        } else {
            response.put("circuitBreakers", new HashMap<>());
            response.put("totalCount", 0);
            response.put("message", "CircuitBreakerRegistry not available");
        }
        
        response.put("timestamp", LocalDateTime.now().format(FORMATTER));
        response.put("service", "gateway-service");
        
        System.out.println("📊 查询熔断器状态 - 共" + response.get("totalCount") + "个熔断器");
        return ResponseEntity.ok(response);
    }

    /**
     * 获取特定熔断器状态
     */
    @GetMapping("/circuit-breaker/{name}")
    public ResponseEntity<Map<String, Object>> getCircuitBreaker(@PathVariable String name) {
        Map<String, Object> response = new HashMap<>();
        
        if (circuitBreakerRegistry != null) {
            try {
                CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker(name);
                response = getCircuitBreakerInfo(circuitBreaker);
                response.put("found", true);
            } catch (Exception e) {
                response.put("found", false);
                response.put("error", "Circuit breaker not found: " + name);
            }
        } else {
            response.put("found", false);
            response.put("error", "CircuitBreakerRegistry not available");
        }
        
        response.put("timestamp", LocalDateTime.now().format(FORMATTER));
        response.put("service", "gateway-service");
        
        System.out.println("📊 查询熔断器状态: " + name + " - " + response.get("found"));
        return ResponseEntity.ok(response);
    }

    /**
     * 获取熔断器详细信息
     */
    private Map<String, Object> getCircuitBreakerInfo(CircuitBreaker circuitBreaker) {
        Map<String, Object> info = new HashMap<>();
        
        info.put("name", circuitBreaker.getName());
        info.put("state", circuitBreaker.getState().toString());
        
        // 获取指标
        CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
        Map<String, Object> metricsInfo = new HashMap<>();
        metricsInfo.put("failureRate", metrics.getFailureRate());
        metricsInfo.put("slowCallRate", metrics.getSlowCallRate());
        metricsInfo.put("numberOfCalls", metrics.getNumberOfBufferedCalls());
        metricsInfo.put("numberOfSuccessfulCalls", metrics.getNumberOfSuccessfulCalls());
        metricsInfo.put("numberOfFailedCalls", metrics.getNumberOfFailedCalls());
        metricsInfo.put("numberOfSlowCalls", metrics.getNumberOfSlowCalls());
        
        info.put("metrics", metricsInfo);
        
        // 状态说明
        String statusDescription = getStateDescription(circuitBreaker.getState());
        info.put("statusDescription", statusDescription);
        
        return info;
    }

    /**
     * 获取状态描述
     */
    private String getStateDescription(CircuitBreaker.State state) {
        switch (state) {
            case CLOSED:
                return "关闭状态 - 正常调用服务";
            case OPEN:
                return "打开状态 - 熔断保护中，拒绝调用";
            case HALF_OPEN:
                return "半开状态 - 尝试恢复，有限调用";
            case DISABLED:
                return "禁用状态 - 熔断器功能已禁用";
            case METRICS_ONLY:
                return "仅指标状态 - 只收集指标，不熔断";
            case FORCED_OPEN:
                return "强制打开状态 - 手动强制熔断";
            default:
                return "未知状态";
        }
    }

    /**
     * 系统弹性概览
     */
    @GetMapping("/overview")
    public ResponseEntity<Map<String, Object>> getResilienceOverview() {
        Map<String, Object> response = new HashMap<>();
        
        // 熔断器概览
        if (circuitBreakerRegistry != null) {
            long totalCB = circuitBreakerRegistry.getAllCircuitBreakers().size();
            long openCB = circuitBreakerRegistry.getAllCircuitBreakers().asJava()
                    .stream()
                    .mapToLong(cb -> cb.getState() == CircuitBreaker.State.OPEN ? 1 : 0)
                    .sum();
            long halfOpenCB = circuitBreakerRegistry.getAllCircuitBreakers().asJava()
                    .stream()
                    .mapToLong(cb -> cb.getState() == CircuitBreaker.State.HALF_OPEN ? 1 : 0)
                    .sum();
            
            Map<String, Object> cbOverview = new HashMap<>();
            cbOverview.put("total", totalCB);
            cbOverview.put("open", openCB);
            cbOverview.put("halfOpen", halfOpenCB);
            cbOverview.put("closed", totalCB - openCB - halfOpenCB);
            cbOverview.put("healthStatus", openCB == 0 ? "healthy" : "degraded");
            
            response.put("circuitBreakers", cbOverview);
        }
        
        // 系统状态
        Map<String, Object> systemStatus = new HashMap<>();
        systemStatus.put("overall", "operational");
        systemStatus.put("resilienceFeatures", new String[]{
            "Circuit Breaker", "Rate Limiting", "Retry", "Timeout", "Fallback"
        });
        
        response.put("system", systemStatus);
        response.put("timestamp", LocalDateTime.now().format(FORMATTER));
        response.put("service", "gateway-service");
        
        System.out.println("📊 查询系统弹性概览");
        return ResponseEntity.ok(response);
    }

    /**
     * 健康检查端点
     */
    @GetMapping("/health")
    public ResponseEntity<Map<String, Object>> health() {
        Map<String, Object> response = new HashMap<>();
        response.put("status", "UP");
        response.put("resilience", "enabled");
        response.put("timestamp", LocalDateTime.now().format(FORMATTER));
        response.put("service", "gateway-service");
        
        System.out.println("💓 容错机制健康检查");
        return ResponseEntity.ok(response);
    }
} 